package com.interview.javabasic;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.*;

/*
@李子宁
Happy,happy everyday!
冲鸭！
2021/3/22

*/
public class TencentDemo {
    private final static Charset UTF8 = StandardCharsets.UTF_8;
   /* private final static String SECRET_ID = "AKIDz8krbsJ5yKBZQpn74WFkmLPx3EXAMPLE";
    private final static String SECRET_KEY = "Gu5t9xGARNpq86cd98joQYCN3EXAMPLE";*/
    private final static String SECRET_ID = "2713c6d9257e6547f9c3c26457132b41";
    private final static String SECRET_KEY = "cb42fe18c3e54b3f9e73415d6d92a715";
    private final static String CT_JSON = "application/json; charset=utf-8";

    public static byte[] hmac256(byte[] key, String msg) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm());
        mac.init(secretKeySpec);
        return mac.doFinal(msg.getBytes(UTF8));
    }

    public static String sha256Hex(String s) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] d = md.digest(s.getBytes(UTF8));
        return DatatypeConverter.printHexBinary(d).toLowerCase();
    }

    public static void main(String[] args) throws Exception {
        String service = "industry";
        String host = "yunxiaowei.qcloud.com";
        String action = "GetAppInfo";
        String version = "v1";
        String algorithm = "HMAC-SHA256";
        //String timestamp = "1551113065";
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 注意时区，否则容易出错
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
        String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));
        System.out.println(date);

        // ************* 步骤 1：拼接规范请求串 *************
        String httpRequestMethod = "POST";
        String canonicalUri = "/industry-cgi";
        String canonicalQueryString = "";
        String canonicalHeaders = "content-type:application/json; charset=utf-8\n";
        String signedHeaders = "content-type";
        Map<String,Object> map = new HashMap<>();
        map.put("product_id","2a_1614677082058_57");
        //String payload = map.toString();
        String payload = "{\"product_id\":\"2a_1614677082058_57\"}";
        System.out.println(payload);
        String hashedRequestPayload = sha256Hex(payload);
        String canonicalRequest = httpRequestMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n"
                + canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;
        System.out.println("canonicalRequest: "+canonicalRequest );

        // ************* 步骤 2：拼接待签名字符串 *************
        String credentialScope = date + "/" + service + "/" + "yxw_request";
        String hashedCanonicalRequest = sha256Hex(canonicalRequest);
        String stringToSign = algorithm + "\n" + timestamp  + "\n" + credentialScope + "\n" + hashedCanonicalRequest;
        System.out.println("stringToSign: " + stringToSign);

        // ************* 步骤 3：计算签名 *************
        byte[] secretDate = hmac256(("YXW" + SECRET_KEY).getBytes(UTF8), date);
        byte[] secretService = hmac256(secretDate, service);
        byte[] secretSigning = hmac256(secretService, "yxw_request");
        String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();
        System.out.println();
        System.out.println();
        System.out.println();
        System.out.println("date: " + date);
        System.out.println("timestamp: "+ timestamp);
        System.out.println("signature: " + signature);

        // ************* 步骤 4：拼接 Authorization *************
        String authorization = algorithm + " " + "Credential=" + SECRET_ID + "/" + credentialScope + ", "
                + "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;
        System.out.println(authorization);

    }
}
